#pragma once

#include "Reactor.hpp"
#include "Sock.hpp"
#include "Util.hpp"
#include <errno.h>
#include <vector>


#define READSIZE 128

// 1: 本轮读取全部完成
//-1: 读取出错
// 0: 对端关闭链接
int RecvCore(int sock, std::string& inbuffer)
{
    while(1)
    {
        char buffer[READSIZE] = {0};
        ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);

        if(s > 0)
        {
            buffer[s] = 0;
            inbuffer += buffer;
        }
        else if(s < 0)
        {
            // 被中断
            if(errno == EINTR)
                continue;
            if(errno == EAGAIN || errno == EWOULDBLOCK)
            {
                // 读完，没数据了
                return 1;
            }

            // 真出问题了
            return -1;
        }
        else
        {
            // 对端关闭
            return 0;
        }
    }
}

int Recver(Event* evp)
{
    std::cout << "有数据准备接收" << std::endl;
    int sock = evp->sock;
    int ret = RecvCore(sock, evp->inbuffer);

    if(ret <= 0)
    {
        if(evp->errorer)
            evp->errorer(evp);
        return -1;
    }

    // 分包
    std::vector<std::string> tokens;
    std::string sep = "X";
    SplitSegment(evp->inbuffer, tokens, sep);
    
    for(auto& task: tokens)
    {
        // 业务处理
        std::string data1, data2;
        // 反序列化
        if(Deserialize(task, &data1, &data2))
        {
            int x = stoi(data1);
            int y = stoi(data2);

            int result = x + y;

            std::string ret = data1;
            ret += '+';
            ret += data2;
            ret += '=';
            ret += std::to_string(result);
            ret += sep;

            evp->outbuffer += ret;
        }
    }

    if(!(evp->outbuffer).empty())
    {
        // 只要设置了EPOLLOUT，至少会触发一次
        evp->R->ChangModeRW(evp, true, true);
    }
}

// 1: 本轮读取全部完成
//-1: 出错
// 0: 缓冲区已满
int SendCore(int sock, std::string& outbuffer)
{
    int total = 0;
    while(1)
    {
        ssize_t ret = send(sock, outbuffer.c_str() + total, outbuffer.size() - total, 0);
        total += ret;

        if(total == outbuffer.size())
        {
            outbuffer.clear();
            return 1;
        }
        else
        {
            if(errno == EINTR)
                continue;
            
            // 写端缓冲区可能已满，不能再写了
            if(errno == EAGAIN || errno == EWOULDBLOCK)
            {
                outbuffer.erase(0, total);
                return 0;
            }

            return -1;
        }
    }
}

int Sender(Event* evp)
{
    std::cout << "有数据准备发送" << std::endl;
    int ret = SendCore(evp->sock, evp->outbuffer);

    if(ret > 0)
    {
        evp->R->ChangModeRW(evp, true, false);
    }
    else if(ret == 0)
    {
        evp->R->ChangModeRW(evp, true, true);
    }
    else 
    {
        if(evp->errorer)
            evp->errorer(evp);
    }
}


int Errorer(Event* evp)
{
    std::cout << "有错误等待处理" << std::endl;
    evp->R->DeleteEvent(evp);
}